/*
 * This file Copyright (c) 2015. Walle.
 * (http://www.wallellen.com). All rights reserved.
 *
 *
 * This file is dual-licensed under both the
 * Walle Agreement (WA) and the GNU General Public License.
 * You may elect to use one or the other of these licenses.
 *
 * This file is distributed in the hope that it will be
 * useful, but AS-IS and WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
 * Redistribution, except as permitted by whichever of the GPL
 * or WA you select, is prohibited.
 *
 * 1. For the GPL license (GPL), you can redistribute and/or
 * modify this file under the terms of the GNU General
 * Public License, Version 3, as published by the Free Software
 * Foundation.  You should have received a copy of the GNU
 * General Public License, Version 3 along with this program;
 * if not, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * 2. For the Walle Agreement (WA), this file
 * and the accompanying materials are made available under the
 * terms of the WA which accompanies this distribution, and
 * is available at http://www.wallellen.com/agreement.html
 *
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 */

package com.wallellen.parameter.service.impl;

import com.wallellen.core.auth.domain.LoginUser;
import com.wallellen.core.sql.query.DBRule;
import com.wallellen.core.sql.query.DBSort;
import com.wallellen.core.sql.query.DataQuery;
import com.wallellen.core.sql.result.DataResult;
import com.wallellen.core.time.TimeTool;
import com.wallellen.parameter.dao.DictionaryEntityDaoInter;
import com.wallellen.parameter.dao.DictionaryTypeDaoInter;
import com.wallellen.parameter.domain.AloneDictionaryEntity;
import com.wallellen.parameter.domain.AloneDictionaryType;
import com.wallellen.parameter.service.DictionaryEntityServiceInter;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.sql.SQLException;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Created by walle on 12/12/15.
 */
@Service
public class DictionaryEntityServiceImpl
        implements DictionaryEntityServiceInter {

    @Resource
    private DictionaryEntityDaoInter dictionaryentityDao;

    @Resource
    private DictionaryTypeDaoInter dictionarytypeDao;
    protected static final Map<String, List<AloneDictionaryType>> dicCache = new HashMap();

    @Transactional
    public void deleteEntity(String entity, LoginUser user) {
        List list = this.dictionarytypeDao
                .getListByEntityId(entity);
        Iterator iterator = list.iterator();
        while (iterator
                .hasNext()) {
            AloneDictionaryType aloneDictionaryType =
                    (AloneDictionaryType) iterator
                            .next();
            this.dictionarytypeDao.deleteEntity(aloneDictionaryType);
        }
        this.dictionaryentityDao.deleteEntity(this.dictionaryentityDao.getEntity(entity));
    }

    @Transactional
    public AloneDictionaryEntity editEntity(AloneDictionaryEntity entity, LoginUser user) {
        dicCache.remove(entity.getEntityindex());
        if (validateIsRepeatKey(entity.getEntityindex(), entity.getId())) {
            throw new IllegalArgumentException("字典KEY已经存在");
        }
        AloneDictionaryEntity entity2 = getEntity(entity.getId());
        entity2.setComments(entity.getComments());
        entity2.setName(entity.getName().trim());
        entity2.setEntityindex(entity.getEntityindex().trim());
        entity2.setUtime(TimeTool.getTimeDate12());
        entity2.setMuser(user.getId());
        entity2.setType(entity.getType());
        this.dictionaryentityDao.editEntity(entity2);
        return entity2;
    }

    public List<AloneDictionaryEntity> getAllEntity() {
        return this.dictionaryentityDao.getAllEntity();
    }

    public int getAllListNum() {
        return 0;
    }

    @Transactional
    public AloneDictionaryEntity getEntity(String id) {
        if (id == null)
            return null;
        return this.dictionaryentityDao.getEntity(id);
    }

    @Transactional
    public AloneDictionaryEntity insertEntity(AloneDictionaryEntity entity, LoginUser user) {
        if (validateIsRepeatKey(entity.getEntityindex(), null)) {
            throw new IllegalArgumentException("字典KEY已经存在");
        }
        entity.setCtime(TimeTool.getTimeDate12());
        entity.setCuser(user.getId());
        entity.setUtime(TimeTool.getTimeDate12());
        entity.setMuser(user.getId());
        entity.setState("1");
        entity.setName(entity.getName().trim());
        entity.setEntityindex(entity.getEntityindex().trim());
        return this.dictionaryentityDao.insertEntity(entity);
    }

    public DictionaryEntityDaoInter getdictionaryentityDao() {
        return this.dictionaryentityDao;
    }

    @Transactional
    public boolean validateIsRepeatKey(String key, String exId) {
        List list = null;
        if ((exId == null) || (exId.trim().equals("")))
            list = this.dictionaryentityDao.findEntityByKey(key.trim());
        else {
            list = this.dictionaryentityDao.findEntityByKey(key.trim(), exId.trim());
        }
        return list.size() > 0;
    }

    public void editComments(String id) {
        if ((id == null) || (id.equals(""))) {
            return;
        }

        AloneDictionaryEntity dicEntity = this.dictionaryentityDao.getEntity(id);

        List<AloneDictionaryType> dictypeList = this.dictionarytypeDao
                .getListByEntityId(id);
        if (dictypeList.isEmpty()) {
            return;
        }

        StringBuilder sBuilder = new StringBuilder();
        sBuilder.append("{");
        for (AloneDictionaryType itDictype : dictypeList) {
            String name = itDictype.getName();
            String entitytype = itDictype.getEntitytype();
            sBuilder.append(name).append(":").append(entitytype).append(", ");
        }
        sBuilder.delete(sBuilder.length() - 2, sBuilder.length());
        sBuilder.append("}");
        if ((sBuilder.toString() != null) && (sBuilder.toString().length() > 100))
            dicEntity
                    .setComments(sBuilder.toString().substring(0, 100) + "...");
        else {
            dicEntity.setComments(sBuilder.toString());
        }
        this.dictionaryentityDao.editEntity(dicEntity);
    }

    public void setdictionaryentityDao(DictionaryEntityDaoInter dictionaryentityDao) {
        this.dictionaryentityDao = dictionaryentityDao;
    }

    public DictionaryTypeDaoInter getDictionarytypeDao() {
        return this.dictionarytypeDao;
    }

    public void setDictionarytypeDao(DictionaryTypeDaoInter dictionarytypeDao) {
        this.dictionarytypeDao = dictionarytypeDao;
    }

    public Map<String, String> getDictionary(String key) {
        Map dic = new HashMap();
        for (AloneDictionaryType node : loadDics(key)) {
            dic.put(node.getEntitytype(), node.getName());
        }
        return dic;
    }

    private List<AloneDictionaryType> loadDics(String key) {
        List types = (List) dicCache.get(key);
        if (types == null) {
            types = new ArrayList();
            DataQuery query =
                    DataQuery.getInstance(1, "b.NAME,b.ENTITYTYPE",
                            "ALONE_DICTIONARY_ENTITY a LEFT JOIN  ALONE_DICTIONARY_TYPE b ON a.ID=b.ENTITY");
            query.addRule(new DBRule("b.STATE", "1", "="));
            query.addRule(new DBRule("a.ENTITYINDEX", key, "="));
            query.addSort(new DBSort("b.SORT", "asc"));
            DataResult result = null;
            try {
                result = query.search();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
            for (Map node : result.getResultList()) {
                AloneDictionaryType type = new AloneDictionaryType();
                type.setEntitytype(node.get("B_ENTITYTYPE").toString());
                type.setName(node.get("B_NAME").toString());
                types.add(type);
            }
            dicCache.put(key, types);
        }
        return types;
    }

    public List<Map.Entry<String, String>> getDictionaryList(String key) {
        List list = new ArrayList();
        for (AloneDictionaryType node : loadDics(key)) {
            Map.Entry entry = new AbstractMap.SimpleEntry(node
                    .getEntitytype(), node.getName());
            list.add(entry);
        }
        return list;
    }

    public String getDicKey(String dicId) {
        return getEntity(dicId).getEntityindex();
    }
}